<template>
  <div class="user-dashboard-container">
    <header class="dashboard-header">
      <h1 class="dashboard-title">用户仪表盘</h1>
      <div class="user-menu-container">
        <!-- 用户菜单按钮 -->
        <button 
          class="user-menu-button"
          @click="toggleUserMenu"
          aria-label="用户菜单"
        >
          <div class="user-avatar">
            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>
          </div>
          <span>{{ currentUser.username }}</span>
          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="chevron"><polyline points="6 9 12 15 18 9"></polyline></svg>
        </button>
        
        <!-- 用户菜单弹出层 -->
        <div v-if="isMenuOpen" class="user-dropdown">
          <div class="dropdown-header">
            <div class="user-info">
              <div class="user-name">{{ currentUser.username }}</div>
              <div class="user-role">{{ currentUser.role }}</div>
            </div>
          </div>
          
          <!-- 用户信息区域 -->
          <div class="user-details">
            <div class="user-detail-item">
              <label>邮箱</label>
              <span>{{ currentUser.email }}</span>
            </div>
            <div class="user-detail-item">
              <label>密码</label>
              <span>{{ maskPassword(currentUser.password) }}</span>
            </div>
          </div>
          
          <div class="dropdown-divider"></div>
          
          <!-- 退出登录按钮 -->
          <div class="logout-button" @click="handleLogout">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
            <span>退出登录</span>
          </div>
        </div>
      </div>
    </header>
    
    <main class="dashboard-content">
      <div class="tasks-section">
        <div class="section-header">
          <h2>我的任务</h2>
          
          <!-- 任务类型切换 -->
          <div class="task-tabs">
            <button 
              class="tab-btn" 
              :class="{ active: activeTab === 'pending' }"
              @click="activeTab = 'pending'"
            >
              待处理任务
            </button>
            <button 
              class="tab-btn" 
              :class="{ active: activeTab === 'processed' }"
              @click="activeTab = 'processed'"
            >
              已处理任务
            </button>
          </div>
        </div>

        <!-- 待处理任务列表 -->
        <div v-if="activeTab === 'pending'">
          <div v-if="userTasks.length > 0" class="task-list">
            <div v-for="task in userTasks" :key="task.id" class="task-item">
              <div class="task-info">
                <h3 class="task-title">{{ task.approverName || 'Unknown Approver' }} - {{ task.taskTypeName || 'Task ' + task.id }}</h3>
                <div class="task-meta">
                  <span class="task-id">ID: {{ task.id }}</span>
                  <span class="task-flow-id">Flow ID: {{ task.taskFlowId }}</span>
                  <span class="task-node-id">Node ID: {{ task.nodeId }}</span>
                  <span class="task-status" :class="`status-${task.status}`">{{ task.statusText || getStatusText(task.status) }}</span>
                </div>
                <div class="task-details">
                  <p class="task-approver">审批人: {{ task.approverName }}</p>
                  <p class="task-time">创建时间: {{ formatDate(task.createdAt) }}</p>
                  <p class="task-time">更新时间: {{ formatDate(task.updatedAt) }}</p>
                </div>
              </div>
              <div class="task-actions">
                <button class="btn btn-primary" @click="viewTaskDetail(task)">查看详情</button>
              </div>
            </div>
          </div>
          
          <!-- 无待处理任务状态 -->
          <div v-else class="no-tasks">
            <div class="no-tasks-icon">📋</div>
            <div class="no-tasks-text">暂无待处理任务</div>
            <div class="no-tasks-subtext">如有任务分配，将显示在此处</div>
          </div>
        </div>

        <!-- 已处理任务列表 -->
        <div v-else-if="activeTab === 'processed'">
          <div v-if="processedTasks.length > 0" class="task-list">
            <div v-for="task in processedTasks" :key="task.id" class="task-item processed-task">
              <div class="task-info">
                <h3 class="task-title">{{ task.approverName || 'Unknown Approver' }} - {{ task.taskTypeName || 'Task ' + task.id }}</h3>
                <div class="task-meta">
                  <span class="task-id">ID: {{ task.id }}</span>
                  <span class="task-flow-id">Flow ID: {{ task.taskFlowId }}</span>
                  <span class="task-node-id">Node ID: {{ task.nodeId }}</span>
                  <span class="task-status status-completed">{{ task.statusText || getStatusText(task.status) }}</span>
                </div>
                <div class="task-details">
                  <p class="task-approver">审批人: {{ task.approverName }}</p>
                  <p class="task-time">创建时间: {{ formatDate(task.createdAt) }}</p>
                  <p class="task-time">更新时间: {{ formatDate(task.updatedAt) }}</p>
                  <div class="task-processed-info" v-if="task.endTime">
                    <span class="processed-time">处理时间: {{ formatDate(task.endTime) }}</span>
                  </div>
                </div>
              </div>
              <div class="task-actions">
                <button class="btn btn-secondary" @click="viewTaskDetail(task)">查看详情</button>
              </div>
            </div>
          </div>
          
          <!-- 无已处理任务状态 -->
          <div v-else class="no-tasks">
            <div class="no-tasks-icon">✅</div>
            <div class="no-tasks-text">暂无已处理任务</div>
            <div class="no-tasks-subtext">您处理完成的任务将显示在此处</div>
          </div>
        </div>
      </div>
    </main>

    <!-- 任务详情模态框 -->
    <div v-if="showTaskDetailModal" class="modal-overlay" @click.self="closeTaskDetailModal">
      <div class="modal-container">
        <div class="modal-header">
          <h3>任务详情 - {{ selectedTask?.approverName || 'Task' }} ({{ selectedTask?.taskTypeName || selectedTask?.id }})</h3>
          <button class="modal-close-btn" @click="closeTaskDetailModal">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <line x1="18" y1="6" x2="6" y2="18"></line>
              <line x1="6" y1="6" x2="18" y2="18"></line>
            </svg>
          </button>
        </div>
        
        <div v-if="selectedTask" class="modal-body">
          <!-- 任务类型和描述信息 -->
          <div v-if="selectedTask.taskTypeName || selectedTask.taskDescription" class="task-type-description">
            <h4>任务信息</h4>
            <div v-if="selectedTask.taskTypeName" class="task-type-name">
              <label>任务类型：</label>
              <span class="markdown-text" v-html="parsedTaskTypeNameHtml"></span>
            </div>
            <div v-if="selectedTask.taskDescription" class="task-description">
              <label>任务描述：</label>
              <div class="markdown-text" v-html="parsedMarkdownHtml"></div>
            </div>
          </div>
          
          <!-- 任务基本信息 -->
          <div class="task-basic-info">
            <div class="info-item">
              <label>任务名称：</label>
              <span>{{ selectedTask.taskTypeName || selectedTask.id }}</span>
            </div>
            <div class="info-item">
              <label>任务流名称：</label>
              <span>{{ selectedTask.flowName || selectedTask.taskFlowId }}</span>
            </div>
            <div class="info-item">
              <label>节点名称：</label>
              <span>{{ selectedTask.nodeName || selectedTask.nodeId }}</span>
            </div>
            <div class="info-item">
              <label>审批人：</label>
              <span>{{ selectedTask.approverName }} ({{ selectedTask.approverAuthId }})</span>
            </div>
            <div class="info-item">
              <label>创建时间：</label>
              <span>{{ formatDate(selectedTask.createdAt) }}</span>
            </div>
            <div class="info-item">
              <label>更新时间：</label>
              <span>{{ formatDate(selectedTask.updatedAt) }}</span>
            </div>
            <div class="info-item">
              <label>任务状态：</label>
              <span class="status-badge" :class="`status-${selectedTask.status}`">{{ selectedTask.statusText || getStatusText(selectedTask.status) }}</span>
            </div>
            <div class="info-item" v-if="selectedTask.comment">
              <label>备注：</label>
              <span>{{ selectedTask.comment }}</span>
            </div>
          </div>

          <!-- 原始数据 (rawData) -->
          <div class="raw-data-section" v-if="selectedTask.rawData">
            <h4>原始数据 (Raw Data)</h4>
            <div class="data-container">
              <div v-if="parseJsonToKeyValuePairs(selectedTask.rawData).length > 0" class="key-value-list">
                <div v-for="(item, index) in parseJsonToKeyValuePairs(selectedTask.rawData)" :key="index" class="key-value-item">
                  <div class="key-value-header">
                    <span class="data-key">{{ item.key }}</span>
                    <span class="data-type-badge" :class="{
                      'badge-object': item.isObject && !item.isArray,
                      'badge-array': item.isArray,
                      'badge-string': typeof item.value === 'string',
                      'badge-number': typeof item.value === 'number',
                      'badge-boolean': typeof item.value === 'boolean',
                      'badge-null': item.value === null || item.value === undefined
                    }">
                      {{ getItemTypeDisplay(item) }}
                    </span>
                  </div>
                  <div class="data-value">
                    <div v-if="!item.isObject || item.value === null" class="simple-value">
                      {{ item.value === null ? 'null' : item.value === undefined ? 'undefined' : item.value }}
                    </div>
                    <div v-else-if="item.isObject" class="expandable-content">
                      <div v-if="item.expanded" class="expanded-content">
                        <div v-if="item.isArray" class="array-content">
                          <div class="array-item-count">共 {{ item.value.length }} 项</div>
                          <div class="nested-key-value-list">
                            <div v-for="(nestedItem, nestedIndex) in parseJsonToKeyValuePairs(item.value)" :key="nestedIndex" class="nested-key-value-item">
                              <div class="key-value-header">
                                <span class="data-key">{{ nestedItem.key }}</span>
                                <span class="data-type-badge" :class="{
                                  'badge-object': nestedItem.isObject && !nestedItem.isArray,
                                  'badge-array': nestedItem.isArray,
                                  'badge-string': typeof nestedItem.value === 'string',
                                  'badge-number': typeof nestedItem.value === 'number',
                                  'badge-boolean': typeof nestedItem.value === 'boolean',
                                  'badge-null': nestedItem.value === null || nestedItem.value === undefined
                                }">
                                  {{ getItemTypeDisplay(nestedItem) }}
                                </span>
                              </div>
                              <div class="data-value">
                                <div v-if="!nestedItem.isObject || nestedItem.value === null" class="simple-value">
                                  {{ nestedItem.value === null ? 'null' : nestedItem.value === undefined ? 'undefined' : nestedItem.value }}
                                </div>
                                <div v-else class="complex-value">{{ formatJsonData(nestedItem.value) }}</div>
                              </div>
                            </div>
                          </div>
                        </div>
                        <div v-else class="object-content">{{ formatJsonData(item.value) }}</div>
                      </div>
                      <div v-else class="collapsed-content">
                        <button class="expand-button" @click.stop="toggleExpand(item)">
                          点击展开 {{ item.isArray ? '数组' : '对象' }}
                        </button>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div v-else class="no-data">暂无原始数据</div>
            </div>
          </div>

          <!-- 额外字段 (extraFields) -->
          <div class="extra-fields-section" v-if="selectedTask.extraFields">
            <h4>额外字段 (Extra Fields)</h4>
            <div class="data-container">
              <div v-if="parseJsonToKeyValuePairs(selectedTask.extraFields).length > 0" class="key-value-list">
                <div v-for="(item, index) in parseJsonToKeyValuePairs(selectedTask.extraFields)" :key="index" class="key-value-item">
                  <div class="key-value-header">
                    <span class="data-key">{{ item.key }}</span>
                    <span class="data-type-badge" :class="{
                      'badge-object': item.isObject && !item.isArray,
                      'badge-array': item.isArray,
                      'badge-string': typeof item.value === 'string',
                      'badge-number': typeof item.value === 'number',
                      'badge-boolean': typeof item.value === 'boolean',
                      'badge-null': item.value === null || item.value === undefined
                    }">
                      {{ getItemTypeDisplay(item) }}
                    </span>
                  </div>
                  <div class="data-value">
                    <div v-if="!item.isObject || item.value === null" class="simple-value">
                      {{ item.value === null ? 'null' : item.value === undefined ? 'undefined' : item.value }}
                    </div>
                    <div v-else-if="item.isObject" class="expandable-content">
                      <div v-if="item.expanded" class="expanded-content">
                        <div v-if="item.isArray" class="array-content">
                          <div class="array-item-count">共 {{ item.value.length }} 项</div>
                          <div class="nested-key-value-list">
                            <div v-for="(nestedItem, nestedIndex) in parseJsonToKeyValuePairs(item.value)" :key="nestedIndex" class="nested-key-value-item">
                              <div class="key-value-header">
                                <span class="data-key">{{ nestedItem.key }}</span>
                                <span class="data-type-badge" :class="{
                                  'badge-object': nestedItem.isObject && !nestedItem.isArray,
                                  'badge-array': nestedItem.isArray,
                                  'badge-string': typeof nestedItem.value === 'string',
                                  'badge-number': typeof nestedItem.value === 'number',
                                  'badge-boolean': typeof nestedItem.value === 'boolean',
                                  'badge-null': nestedItem.value === null || nestedItem.value === undefined
                                }">
                                  {{ getItemTypeDisplay(nestedItem) }}
                                </span>
                              </div>
                              <div class="data-value">
                                <div v-if="!nestedItem.isObject || nestedItem.value === null" class="simple-value">
                                  {{ nestedItem.value === null ? 'null' : nestedItem.value === undefined ? 'undefined' : nestedItem.value }}
                                </div>
                                <div v-else class="complex-value">{{ formatJsonData(nestedItem.value) }}</div>
                              </div>
                            </div>
                          </div>
                        </div>
                        <div v-else class="object-content">{{ formatJsonData(item.value) }}</div>
                      </div>
                      <div v-else class="collapsed-content">
                        <button class="expand-button" @click.stop="toggleExpand(item)">
                          点击展开 {{ item.isArray ? '数组' : '对象' }}
                        </button>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div v-else class="no-data">暂无额外字段</div>
            </div>
          </div>

          <!-- 节点内容 (nodeContent) - 表单设计器组件 -->
          <div class="node-content-section" v-if="selectedTask.nodeContent">
            <h4>表单设计器组件 (Form Designer Components)</h4>
            <div class="node-content-container">
              <div v-if="getParsedNodeContent(selectedTask.nodeContent).length > 0" class="form-designer-components">
                <div class="form-designer-info">
                  <p class="section-description">以下是表单设计器中配置的输入组件，您可以直接在此处填写和编辑：</p>
                </div>
                
                <!-- 动态生成的表单控件 -->
                <div v-if="activeTab === 'pending' && selectedTask.status !== 'completed'" class="dynamic-form-container">
                  <form @submit.prevent="submitForm" class="task-form">
                    <div v-for="(component, index) in getParsedNodeContent(selectedTask.nodeContent)" :key="component.id || index" class="form-component">
                      <!-- 组件标签 -->
                      <label :for="'field-' + (component.id || index)" class="form-label" :class="{ required: component.required }">{{ component.label || component.name }}</label>
                       
                      <!-- 单行文本输入框 -->
                      <input v-if="['input', 'text', 'email', 'password', 'number', 'url', 'tel', 'search'].includes(component.type)"
                             :id="'field-' + (component.id || index)"
                             :type="component.type === 'text' ? 'text' : component.type"
                             :name="component.name"
                             v-model="formData[component.name]"
                             :placeholder="component.placeholder || ''"
                             :required="component.required"
                             :maxlength="component.maxLength"
                             :min="component.min"
                             :max="component.max"
                             :step="component.step"
                             :pattern="component.pattern"
                             :disabled="component.disabled"
                             class="form-control"
                             @input="handleFormInput($event, component)"/>
                       
                      <!-- 多行文本输入框 -->
                      <textarea v-else-if="component.type === 'textarea'"
                                :id="'field-' + (component.id || index)"
                                :name="component.name"
                                v-model="formData[component.name]"
                                :placeholder="component.placeholder || ''"
                                :required="component.required"
                                :maxlength="component.maxLength"
                                :disabled="component.disabled"
                                class="form-control"
                                @input="handleFormInput($event, component)"></textarea>
                       
                      <!-- 下拉选择框 -->
                      <select v-else-if="component.type === 'select'"
                              :id="'field-' + (component.id || index)"
                              :name="component.name"
                              v-model="formData[component.name]"
                              :required="component.required"
                              :disabled="component.disabled"
                              class="form-control"
                              @change="handleFormInput($event, component)">
                        <option value="" disabled>请选择...</option>
                        <option v-for="(option, optIdx) in component.options" :key="optIdx" :value="option.value || option">
                          {{ option.label || option.text || option }}
                        </option>
                      </select>
                       
                      <!-- 单选按钮组 -->
                      <div v-else-if="component.type === 'radio'" class="radio-group">
                        <label v-for="(option, optIdx) in component.options" :key="optIdx" class="radio-option">
                          <input type="radio"
                                 :id="'field-' + (component.id || index) + '-' + optIdx"
                                 :name="component.name"
                                 :value="option.value || option"
                                 :checked="formData[component.name] === (option.value || option)"
                                 :disabled="component.disabled"
                                 @change="handleFormInput($event, component)"/>
                          <span>{{ option.label || option.text || option }}</span>
                        </label>
                      </div>
                       
                      <!-- 复选框组 -->
                      <div v-else-if="component.type === 'checkbox'" class="checkbox-group">
                        <label v-for="(option, optIdx) in component.options" :key="optIdx" class="checkbox-option">
                          <input type="checkbox"
                                 :id="'field-' + (component.id || index) + '-' + optIdx"
                                 :name="component.name"
                                 :value="option.value || option"
                                 :checked="formData[component.name] && formData[component.name].includes(option.value || option)"
                                 :disabled="component.disabled"
                                 @change="handleFormInput($event, component)"/>
                          <span>{{ option.label || option.text || option }}</span>
                        </label>
                      </div>
                       
                      <!-- 日期时间选择器 -->
                      <input v-else-if="['date', 'datetime', 'month', 'week', 'time'].includes(component.type)"
                             :id="'field-' + (component.id || index)"
                             :type="component.type === 'datetime' ? 'datetime-local' : component.type"
                             :name="component.name"
                             v-model="formData[component.name]"
                             :required="component.required"
                             :disabled="component.disabled"
                             class="form-control"
                             @change="handleFormInput($event, component)"/>
                      
                      <!-- 范围选择器 -->
                      <input v-else-if="component.type === 'range'"
                             :id="'field-' + (component.id || index)"
                             type="range"
                             :name="component.name"
                             v-model="formData[component.name]"
                             :min="component.min || 0"
                             :max="component.max || 100"
                             :step="component.step || 1"
                             :disabled="component.disabled"
                             class="form-control range-input"
                             @input="handleFormInput($event, component)"/>
                      
                      <!-- 颜色选择器 -->
                      <input v-else-if="component.type === 'color'"
                             :id="'field-' + (component.id || index)"
                             type="color"
                             :name="component.name"
                             v-model="formData[component.name]"
                             :required="component.required"
                             :disabled="component.disabled"
                             class="form-control color-input"
                             @input="handleFormInput($event, component)"/>
                        
                      <!-- 开关按钮 -->
                      <label v-else-if="component.type === 'switch'" class="switch-control">
                        <input type="checkbox"
                               :id="'field-' + (component.id || index)"
                               :name="component.name"
                               v-model="formData[component.name]"
                               :disabled="component.disabled"
                               @change="handleFormInput($event, component)"/>
                        <span class="switch-slider"></span>
                      </label>
                       
                      <!-- 文件上传 -->
                      <div v-else-if="component.type === 'file'" class="file-upload">
                        <label :for="'field-' + (component.id || index)" class="file-label">
                          <input type="file"
                                 :id="'field-' + (component.id || index)"
                                 :name="component.name"
                                 :multiple="component.multiple"
                                 :accept="component.accept"
                                 :disabled="component.disabled"
                                 @change="handleFileUpload($event, component)"/>
                          <span class="file-text">{{ formData[component.name] ? '已选择文件' : '点击上传文件' }}</span>
                        </label>
                      </div>
                       
                      <!-- 隐藏字段 -->
                      <input v-else-if="component.type === 'hidden'"
                             :id="'field-' + (component.id || index)"
                             type="hidden"
                             :name="component.name"
                             v-model="formData[component.name]"/>
                        
                      <!-- 数组类型组件 -->
                      <div v-else-if="component.type === 'array'" class="array-component">
                        <div class="array-items">
                          <div v-for="(item, itemIdx) in (formData[component.name] || [])" :key="itemIdx" class="array-item">
                            <input 
                              :id="'field-' + (component.id || index) + '-item-' + itemIdx"
                              type="text"
                              :value="item"
                              @input="handleArrayInputChange(component, $event.target.value, itemIdx)"
                              :placeholder="component.itemPlaceholder || '请输入值'"
                              :disabled="component.disabled"
                              class="form-control array-item-input"
                            />
                            <button 
                              type="button" 
                              class="btn btn-danger btn-sm array-remove-btn"
                              @click="removeArrayItem(component, itemIdx)"
                              :disabled="component.disabled"
                            >
                              删除
                            </button>
                          </div>
                        </div>
                        <button 
                          type="button" 
                          class="btn btn-secondary btn-sm array-add-btn"
                          @click="handleArrayInputChange(component, '', -1)"
                          :disabled="component.disabled"
                        >
                          添加新项
                        </button>
                      </div>
                        
                      <!-- 未知组件类型显示 -->
                      <div v-else class="unknown-component">
                        <div class="form-control readonly">
                          组件类型：{{ component.type || '未知' }}
                        </div>
                      </div>
                       
                      <!-- 组件帮助信息 -->
                      <div v-if="component.description" class="component-description">{{ component.description }}</div>
                    </div>
                    
                    <!-- 表单提交按钮 -->
                    <div class="form-actions">
                      <button type="button" class="btn btn-secondary" @click="closeTaskDetailModal">关闭</button>
                      <button type="submit" class="btn btn-primary" :disabled="!canSubmitForm">提交</button>
                    </div>
                  </form>
                </div>
                
                <!-- 只读模式的表单组件列表 -->
                <div v-else class="form-components-list">
                  <div v-for="(component, index) in getParsedNodeContent(selectedTask.nodeContent)" :key="component.id || index" class="form-component-card">
                    <!-- 组件头部信息 -->
                    <div class="component-header">
                      <div class="component-icon-wrapper">
                        <span class="component-icon">{{ component.icon || '📝' }}</span>
                      </div>
                      <div class="component-title-info">
                        <h5 class="component-name">{{ component.name || 'Unknown Component' }}</h5>
                        <span class="component-type-badge">{{ component.type || 'unknown' }}</span>
                      </div>
                      <div class="component-required-badge" v-if="component.required">
                        <span class="required-text">必填</span>
                      </div>
                    </div>
                    
                    <!-- 组件详细信息 -->
                    <div class="component-body">
                      <div class="component-label">
                        <strong>字段标签:</strong> {{ component.label || '未设置' }}
                      </div>
                      
                      <!-- 组件值（只读模式） -->
                      <div class="component-value" v-if="formData[component.name] !== undefined">
                        <strong>当前值:</strong> 
                        <div class="read-only-value">
                          <div v-if="Array.isArray(formData[component.name])">
                            <div class="array-items-display">
                              <span v-for="(item, idx) in formData[component.name]" :key="idx" class="array-item">{{ item }}</span>
                            </div>
                          </div>
                          <div v-else-if="typeof formData[component.name] === 'object'">
                            <pre class="json-data-small">{{ formatJsonData(formData[component.name]) }}</pre>
                          </div>
                          <div v-else>
                            {{ formData[component.name] || '无' }}
                          </div>
                        </div>
                      </div>
                      
                      <div class="component-properties">
                        <div class="property-item">
                          <span class="property-label">组件ID:</span>
                          <span class="property-value">{{ component.id || 'N/A' }}</span>
                        </div>
                        <div class="property-item">
                          <span class="property-label">组件类型:</span>
                          <span class="property-value">{{ getComponentTypeDisplay(component.type) }}</span>
                        </div>
                        <div class="property-item">
                          <span class="property-label">宽度设置:</span>
                          <span class="property-value">{{ component.width || '默认' }}</span>
                        </div>
                        <div class="property-item">
                          <span class="property-label">是否必填:</span>
                          <span class="property-value" :class="component.required ? 'required-yes' : 'required-no'">
                            {{ component.required ? '是' : '否' }}
                          </span>
                        </div>
                      </div>
                      
                      <!-- 组件特殊属性 -->
                      <div class="component-extra-props" v-if="hasExtraProperties(component)">
                        <h6>组件特殊属性:</h6>
                        <div class="extra-props-list">
                          <div v-if="component.placeholder" class="extra-prop">
                            <span class="prop-name">占位符:</span>
                            <span class="prop-value">{{ component.placeholder }}</span>
                          </div>
                          <div v-if="component.defaultValue !== undefined" class="extra-prop">
                            <span class="prop-name">默认值:</span>
                            <span class="prop-value">{{ component.defaultValue }}</span>
                          </div>
                          <div v-if="component.maxLength" class="extra-prop">
                            <span class="prop-name">最大长度:</span>
                            <span class="prop-value">{{ component.maxLength }}</span>
                          </div>
                          <div v-if="component.min" class="extra-prop">
                            <span class="prop-name">最小值:</span>
                            <span class="prop-value">{{ component.min }}</span>
                          </div>
                          <div v-if="component.max" class="extra-prop">
                            <span class="prop-name">最大值:</span>
                            <span class="prop-value">{{ component.max }}</span>
                          </div>
                          <div v-if="component.options && component.options.length > 0" class="extra-prop">
                            <span class="prop-name">选项列表:</span>
                            <div class="options-list">
                              <span v-for="(option, idx) in component.options" :key="idx" class="option-item">
                                {{ option.label || option.text || option }}
                              </span>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              
              <!-- 如果解析失败，显示原始JSON -->
              <div v-else class="fallback-json-display">
                <p class="fallback-info">无法解析表单组件，显示原始数据：</p>
                <pre class="json-data">{{ formatJsonData(selectedTask.nodeContent) }}</pre>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, watch, markRaw } from 'vue';
import { useRouter } from 'vue-router';
import taskService from '../services/taskService';
import taskApprovalService from '../services/taskApprovalService';

// 动态导入markdown-it并配置支持完整的Markdown语法
let mdParser = null;
import('markdown-it').then(module => {
  mdParser = markRaw(module.default({
    html: true,       // 允许HTML标签
    linkify: true,    // 自动识别链接
    typographer: true // 替换美化
  }));
});

const router = useRouter();

// 解析 Markdown 内容
const parseMarkdown = (markdown) => {
  if (!markdown || !mdParser) {
    return markdown || '';
  }
  try {
    // 预处理Markdown内容，确保标题#后面有空格（支持所有级别标题：#到######）
    let processedMarkdown = markdown.replace(/(^|\n)(#{1,6})(\S)/g, '$1$2 $3');
    
    // 调用配置好的markdown-it进行完整解析
    const result = mdParser.render(processedMarkdown);
    
    // 为解析结果添加统一的样式类，并去掉标题前的#符号
    // 注意：这里通过正则表达式处理HTML结果，移除标题标签内的#符号
    // 使用markdown-content类以支持列表缩进样式
    const styledResult = `<div class="markdown-content">${result.replace(/<(h[1-6])>(\s*#{1,6}\s*)(.*?)<\/\1>/g, '<$1>$3</$1>')}</div>`;
    
    return styledResult;
  } catch (error) {
    console.error('Markdown解析错误:', error);
    // 出错时返回原始文本，但添加基本样式
    return `<div class="markdown-content">${markdown}</div>`;
  }
};

// 存储解析后的markdown HTML
const parsedMarkdownHtml = ref('');
const parsedTaskTypeNameHtml = ref('');

// 用户任务列表
const userTasks = ref([]);
// 已处理任务列表
const processedTasks = ref([]);
// 当前激活的标签页
const activeTab = ref('pending');
// 是否显示任务详情模态框
const showTaskDetailModal = ref(false);
// 当前选中的任务
const selectedTask = ref(null);
// 当前用户角色
const currentUserRole = ref('普通用户');
// 当前用户ID
const currentUserId = ref(null);
// 选中任务的流程节点
const selectedTaskProcess = ref({ nodes: [] });
// 用户任务节点表单
const userTaskNodeForm = ref(null);
// 表单数据
const formData = ref({});

// 提交按钮状态
const canSubmitForm = computed(() => {
  // 简单验证：至少有一个表单字段有值
  return Object.values(formData.value).some(value => {
    if (Array.isArray(value)) {
      return value.length > 0;
    }
    if (value === null || value === undefined) {
      return false;
    }
    return String(value).trim() !== '';
  });
});

// 从localStorage获取当前用户信息
const currentUser = computed(() => {
  const userData = localStorage.getItem('user');
  if (userData) {
    try {
      const user = JSON.parse(userData);
      // 处理嵌套的userInfo对象
      const userInfo = user.userInfo || user;
      // 提供默认值，以防数据不完整
      return {
        username: userInfo.userName || '用户',
        email: userInfo.email || 'user@example.com',
        password: userInfo.password || '',
        role: userInfo.userType || userInfo.role || '普通用户'
      };
    } catch (error) {
      console.error('解析用户数据失败:', error);
    }
  }
  // 返回默认用户信息
  return {
    username: '用户',
    email: 'user@example.com',
    password: '',
    role: '普通用户'
  };
});

// 切换菜单显示状态
const isMenuOpen = ref(false);

const toggleUserMenu = () => {
  isMenuOpen.value = !isMenuOpen.value;
};

// 密码掩码函数
const maskPassword = (password) => {
  if (!password) return '********';
  return '*'.repeat(password.length);
};

// 处理退出登录逻辑
const handleLogout = () => {
  // 清除本地存储中的用户信息和令牌
  localStorage.removeItem('user');
  localStorage.removeItem('token');
  localStorage.removeItem('rememberedAuthId');
  
  // 重定向到登录页面
  router.push('/login');
};

// 组件挂载时检查用户是否已登录
const checkLoginStatus = () => {
  const user = localStorage.getItem('user');
  const token = localStorage.getItem('token');
  
  if (!user || !token) {
    // 如果没有用户信息或令牌，重定向到登录页面
    router.push('/login');
  } else {
    try {
      const userInfo = JSON.parse(user);
      // 获取用户角色和用户ID信息
      currentUserRole.value = userInfo.role || userInfo.userType || '普通用户';
      currentUserId.value = userInfo.id || userInfo.userId;
      
      console.log('用户登录信息:', {
        userId: currentUserId.value,
        role: currentUserRole.value,
        userInfo: userInfo
      });
      
      // 检查用户ID是否存在
      if (!currentUserId.value) {
        console.error('用户ID未找到，请重新登录');
        showMessage('用户信息不完整，请重新登录', 'error');
        setTimeout(() => {
          router.push('/login');
        }, 2000);
        return;
      }
      
      // 加载用户任务
      loadUserTasks();
    } catch (error) {
      console.error('解析用户信息失败:', error);
      router.push('/login');
    }
  }
};

// 点击页面其他区域关闭用户菜单
window.addEventListener('click', (e) => {
  const userMenuContainer = document.querySelector('.user-menu-container');
  if (userMenuContainer && !userMenuContainer.contains(e.target)) {
    isMenuOpen.value = false;
  }
});

// 生成模拟待处理任务数据
const generateMockTasks = () => {
  // 模拟数据包含当前用户角色相关的任务
  const mockTasks = [
    {
      id: '1',
      title: '数据同步任务',
      taskType: '数据处理',
      department: '技术部',
      status: 'pending',
      createdAt: new Date().toISOString(),
      description: '完成MySQL数据源的数据同步工作',
      assignedToRole: '普通用户'
    },
    {
      id: '2',
      title: '系统升级部署验证',
      taskType: '测试验证',
      department: '测试部',
      status: 'pending',
      createdAt: new Date(Date.now() - 86400000).toISOString(),
      description: '验证系统升级后的功能稳定性',
      assignedToRole: '普通用户'
    },
    {
      id: '3',
      title: '用户数据导入',
      taskType: '数据处理',
      department: '数据部',
      status: 'processing',
      createdAt: new Date(Date.now() - 3600000).toISOString(),
      description: '从Excel文件导入新用户数据到系统',
      assignedToRole: '普通用户'
    },
    {
      id: '4',
      title: '季度报表生成',
      taskType: '报表生成',
      department: '财务部',
      status: 'pending',
      createdAt: new Date(Date.now() - 172800000).toISOString(),
      description: '生成第二季度财务报表',
      assignedToRole: '普通用户'
    },
    {
      id: '5',
      title: '系统日志分析',
      taskType: '系统维护',
      department: '技术部',
      status: 'pending',
      createdAt: new Date().toISOString(),
      description: '分析过去一周的系统日志，排查潜在问题',
      assignedToRole: '普通用户'
    },
    {
      id: '6',
      title: '用户使用情况调查',
      taskType: '数据收集',
      department: '产品部',
      status: 'pending',
      createdAt: new Date(Date.now() - 3600000 * 2).toISOString(),
      description: '通过问卷形式收集用户对系统功能的使用反馈',
      assignedToRole: '普通用户'
    }
  ];
  
  // 过滤出与当前用户ID相关的待处理或处理中的任务
  return mockTasks.filter(task => {
    // 模拟数据：将所有任务分配给当前用户
    task.assignedToUserId = currentUserId.value;
    task.assignedToRole = currentUserRole.value;
    return task.status === 'pending' || task.status === 'processing';
  });
};

// 生成模拟已处理任务数据
const generateMockProcessedTasks = () => {
  const mockProcessedTasks = [
    {
      id: 'proc-1',
      title: '产品库存盘点',
      taskType: '数据处理',
      department: '库存部',
      status: 'completed',
      createdAt: new Date(Date.now() - 86400000 * 5).toISOString(),
      processedAt: new Date(Date.now() - 86400000 * 3).toISOString(),
      description: '完成Q3季度产品库存盘点与数据整理',
      assignedToRole: '普通用户',
      // 添加已提交的表单数据
      submittedFormData: {
        status: '已完成全部盘点',
        description: 'Q3季度库存盘点工作已完成，共盘点32个SKU，发现差异5处，已全部核实修正。',
        completionStatus: 'completed',
        totalItems: '12568',
        discrepancyItems: '5'
      }
    },
    {
      id: 'proc-2',
      title: '客户满意度调查分析',
      taskType: '数据分析',
      department: '客服部',
      status: 'completed',
      createdAt: new Date(Date.now() - 86400000 * 7).toISOString(),
      processedAt: new Date(Date.now() - 86400000 * 2).toISOString(),
      description: '分析第三季度客户满意度调查结果',
      assignedToRole: '普通用户',
      // 添加已提交的表单数据
      submittedFormData: {
        analysisSummary: '第三季度客户满意度为92%，较上季度提升3%',
        keyFindings: '产品质量满意度最高，客户服务响应速度有待提升',
        improvementSuggestions: '建议增加客服人员，优化响应流程',
        overallRating: 'excellent'
      }
    },
    {
      id: 'proc-3',
      title: '系统性能优化报告',
      taskType: '技术文档',
      department: '技术部',
      status: 'completed',
      createdAt: new Date(Date.now() - 86400000 * 10).toISOString(),
      processedAt: new Date(Date.now() - 86400000 * 5).toISOString(),
      description: '编写系统性能优化方案与实施报告',
      assignedToRole: '普通用户',
      // 添加已提交的表单数据
      submittedFormData: {
        optimizationAreas: '数据库查询、前端渲染、API响应时间',
        performanceImprovement: '平均响应时间从2.5秒降低到0.8秒',
        implementationDetails: '优化了数据库索引，引入了缓存机制，前端代码分割',
        nextSteps: '监控系统运行状况，持续优化'
      }
    }
  ];
  
  // 过滤出与当前用户ID相关的已完成任务
  return mockProcessedTasks.filter(task => {
    // 模拟数据：将所有已完成任务分配给当前用户
    task.assignedToUserId = currentUserId.value;
    task.assignedToRole = currentUserRole.value;
    return task.status === 'completed';
  });
};

// 加载用户任务
const loadUserTasks = async () => {
  try {
    // 检查用户ID是否存在
    if (!currentUserId.value) {
      console.error('用户ID不存在，无法加载任务');
      showMessage('用户信息缺失，请重新登录', 'error');
      return;
    }

    console.log('开始加载用户任务，用户ID:', currentUserId.value);
    
    // 调用真实的API获取用户待处理任务
    try {
      console.log(`开始调用API: /api/task-approval-status/approver/${currentUserId.value}/processing-with-rawdata`);
      
      const response = await taskService.getUserTasks(currentUserId.value);
      
      console.log('API调用成功，返回数据:', response);
      console.log('响应数据类型:', typeof response);
      console.log('响应数据结构:', {
        hasData: !!response?.data,
        dataType: typeof response?.data,
        isArray: Array.isArray(response?.data),
        dataLength: Array.isArray(response?.data) ? response.data.length : 'N/A'
      });
      
      if (response && response.data) {
        // 处理API返回的数据
        const apiTasks = Array.isArray(response.data) ? response.data : [];
        console.log(`获取到 ${apiTasks.length} 个任务记录`);
        
        // 打印第一个任务的结构以供调试
        if (apiTasks.length > 0) {
          console.log('第一个任务的数据结构:', apiTasks[0]);
          console.log('任务字段:', Object.keys(apiTasks[0]));
        }
        
        // 分离待处理和已处理任务
        userTasks.value = apiTasks.filter(task => 
          task.status === 1 || task.status === 'pending' || task.status === 'processing' || !task.isCompleted
        );
        
        processedTasks.value = apiTasks.filter(task => 
          task.status === 2 || task.status === 'completed' || task.isCompleted
        );
        
        console.log('待处理任务数量:', userTasks.value.length);
        console.log('已处理任务数量:', processedTasks.value.length);
        
        showMessage(`成功加载 ${apiTasks.length} 个任务`, 'success');
      } else {
        console.warn('API返回数据格式异常:', response);
        userTasks.value = [];
        processedTasks.value = [];
        showMessage('暂无任务数据', 'info');
      }
    } catch (apiError) {
      console.error('API调用失败:', apiError);
      
      // API调用失败时使用备用模拟数据
      console.log('使用备用模拟数据');
      userTasks.value = generateMockTasks();
      processedTasks.value = generateMockProcessedTasks();
      
      showMessage('API调用失败，已加载模拟数据', 'warning');
    }
  } catch (error) {
    console.error('加载任务时发生错误:', error);
    
    // 发生错误时使用备选模拟数据
    userTasks.value = [
      {
        id: 'fallback-1',
        title: '数据同步任务',
        taskType: '数据处理',
        department: '技术部',
        status: 'pending',
        createdAt: new Date().toISOString(),
        description: '完成MySQL数据源的数据同步工作',
        assignedToUserId: currentUserId.value,
        assignedToRole: currentUserRole.value
      },
      {        
        id: 'fallback-2',
        title: '系统升级部署验证',
        taskType: '测试验证',
        department: '测试部',
        status: 'processing',
        createdAt: new Date(Date.now() - 86400000).toISOString(),
        description: '验证系统升级后的功能稳定性',
        assignedToUserId: currentUserId.value,
        assignedToRole: currentUserRole.value
      }
    ];
    
    // 加载备用已处理任务数据
    processedTasks.value = [
      {
        id: 'fallback-proc-1',
        title: '产品库存盘点',
        taskType: '数据处理',
        department: '库存部',
        status: 'completed',
        createdAt: new Date(Date.now() - 86400000 * 5).toISOString(),
        processedAt: new Date(Date.now() - 86400000 * 3).toISOString(),
        description: '完成Q3季度产品库存盘点与数据整理',
        assignedToUserId: currentUserId.value,
        assignedToRole: currentUserRole.value
      }
    ];
    
    showMessage('加载任务数据时发生错误，已使用备用模拟数据', 'error');
  }
  
  // 确保数据已设置
  console.log('当前用户任务列表长度:', userTasks.value.length);
};

// 显示提示消息
const showMessage = (message, type = 'info') => {
  // 创建消息元素
  const msgElement = document.createElement('div');
  msgElement.className = `message-toast message-${type}`;
  msgElement.textContent = message;
  
  // 添加样式
  msgElement.style.position = 'fixed';
  msgElement.style.top = '20px';
  msgElement.style.right = '20px';
  msgElement.style.padding = '12px 20px';
  msgElement.style.borderRadius = '4px';
  msgElement.style.color = 'white';
  msgElement.style.fontSize = '14px';
  msgElement.style.zIndex = '9999';
  msgElement.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)';
  msgElement.style.transition = 'all 0.3s ease';
  msgElement.style.opacity = '0';
  msgElement.style.transform = 'translateY(-20px)';
  
  // 根据消息类型设置背景色
  if (type === 'success') {
    msgElement.style.backgroundColor = '#52c41a';
  } else if (type === 'warning') {
    msgElement.style.backgroundColor = '#faad14';
  } else if (type === 'error') {
    msgElement.style.backgroundColor = '#ff4d4f';
  } else {
    msgElement.style.backgroundColor = '#1890ff';
  }
  
  // 添加到文档
  document.body.appendChild(msgElement);
  
  // 显示消息
  setTimeout(() => {
    msgElement.style.opacity = '1';
    msgElement.style.transform = 'translateY(0)';
  }, 10);
  
  // 3秒后自动移除
  setTimeout(() => {
    msgElement.style.opacity = '0';
    msgElement.style.transform = 'translateY(-20px)';
    setTimeout(() => {
      document.body.removeChild(msgElement);
    }, 300);
  }, 3000);
};

// 查看任务详情
const viewTaskDetail = (task) => {
  selectedTask.value = task;
  // 模拟获取任务流程节点
  fetchTaskProcessNodes(task);
  // 解析任务描述的markdown
  if (task.taskDescription) {
    parsedMarkdownHtml.value = parseMarkdown(task.taskDescription);
  } else {
    parsedMarkdownHtml.value = '';
  }
  // 解析任务类型名称的markdown
  if (task.taskTypeName) {
    parsedTaskTypeNameHtml.value = parseMarkdown(task.taskTypeName);
  } else {
    parsedTaskTypeNameHtml.value = '';
  }
  // 显示任务详情模态框
  showTaskDetailModal.value = true;
};

// 获取任务流程节点
const fetchTaskProcessNodes = (task) => {
  // 根据不同任务类型提供不同的流程
  if (task.taskType === '数据处理') {
    selectedTaskProcess.value = {
      id: 'proc_data',
      name: '数据处理流程',
      nodes: [
        {
          id: 'node1',
          nodeName: '数据准备',
          role: '数据管理员',
          status: 'completed'
        },
        {
          id: 'node2',
          nodeName: '数据同步',
          role: '普通用户',
          status: 'pending'
        },
        {
          id: 'node3',
          nodeName: '数据验证',
          role: '数据分析师',
          status: 'pending'
        },
        {
          id: 'node4',
          nodeName: '结果归档',
          role: '管理员',
          status: 'pending'
        }
      ]
    };
  } else if (task.taskType === '测试验证') {
    selectedTaskProcess.value = {
      id: 'proc_test',
      name: '测试验证流程',
      nodes: [
        {
          id: 'node1',
          nodeName: '测试准备',
          role: '测试负责人',
          status: 'completed'
        },
        {
          id: 'node2',
          nodeName: '功能测试',
          role: '普通用户',
          status: 'pending'
        },
        {
          id: 'node3',
          nodeName: '性能测试',
          role: '测试工程师',
          status: 'pending'
        },
        {
          id: 'node4',
          nodeName: '测试报告',
          role: '测试负责人',
          status: 'pending'
        }
      ]
    };
  } else {
    // 默认流程
    selectedTaskProcess.value = {
      id: 'proc1',
      name: '标准审批流程',
      nodes: [
        {
          id: 'node1',
          nodeName: '任务创建',
          role: '发起人',
          status: 'completed'
        },
        {
          id: 'node2',
          nodeName: '任务执行',
          role: '普通用户',
          status: 'pending'
        },
        {
          id: 'node3',
          nodeName: '结果审核',
          role: '部门经理',
          status: 'pending'
        }
      ]
    };
  }
  
  // 查找用户需要处理的节点，并加载对应表单
  const userNode = selectedTaskProcess.value.nodes.find(node => node.role === currentUserRole.value);
  if (userNode) {
    loadUserNodeForm(userNode, task.id);
  }
};

// 加载用户节点表单
const loadUserNodeForm = (node, taskId) => {
  // 根据节点类型提供不同的表单
  if (node.nodeName === '数据同步') {
    userTaskNodeForm.value = {
      id: `form_${taskId}_${node.id}`,
      taskId: taskId,
      nodeId: node.id,
      formComponents: [
        {
          id: 'input1',
          type: 'input',
          label: '同步数据源',
          name: 'dataSource',
          placeholder: '请输入数据源名称'
        },
        {
          id: 'textarea1',
          type: 'textarea',
          label: '同步说明',
          name: 'description',
          placeholder: '请描述同步过程和结果'
        },
        {
          id: 'select1',
          type: 'select',
          label: '同步状态',
          name: 'status',
          options: [
            { value: 'success', label: '成功' },
            { value: 'partial', label: '部分成功' },
            { value: 'failed', label: '失败' }
          ]
        },
        {
          id: 'checkbox1',
          type: 'checkbox',
          label: '同步内容',
          name: 'syncContent',
          options: [
            { value: 'table1', label: '用户表' },
            { value: 'table2', label: '订单表' },
            { value: 'table3', label: '产品表' },
            { value: 'table4', label: '日志表' },
            { value: 'table5', label: '配置表' }
          ]
        },
        {
          id: 'radio1',
          type: 'radio',
          label: '同步方式',
          name: 'syncMode',
          options: [
            { value: 'full', label: '全量同步' },
            { value: 'incremental', label: '增量同步' },
            { value: 'differential', label: '差异同步' }
          ]
        },
        {
          id: 'input2',
          type: 'input',
          label: '影响行数',
          name: 'affectedRows',
          placeholder: '请输入同步影响的行数'
        }
      ]
    };
  } else if (node.nodeName === '功能测试') {
    userTaskNodeForm.value = {
      id: `form_${taskId}_${node.id}`,
      taskId: taskId,
      nodeId: node.id,
      formComponents: [
        {
          id: 'input1',
          type: 'input',
          label: '测试版本',
          name: 'version',
          placeholder: '请输入测试版本号'
        },
        {
          id: 'textarea1',
          type: 'textarea',
          label: '测试记录',
          name: 'testRecord',
          placeholder: '请详细描述测试过程和结果'
        },
        {
          id: 'select1',
          type: 'select',
          label: '测试结果',
          name: 'result',
          options: [
            { value: 'pass', label: '通过' },
            { value: 'fail', label: '失败' },
            { value: 'blocked', label: '阻塞' },
            { value: 'partial_pass', label: '部分通过' }
          ]
        },
        {
          id: 'checkbox1',
          type: 'checkbox',
          label: '测试功能点',
          name: 'testPoints',
          options: [
            { value: 'login', label: '登录功能' },
            { value: 'dashboard', label: '仪表盘展示' },
            { value: 'data_import', label: '数据导入' },
            { value: 'report_export', label: '报表导出' },
            { value: 'user_management', label: '用户管理' }
          ]
        },
        {
          id: 'input2',
          type: 'input',
          label: '缺陷数量',
          name: 'bugCount',
          placeholder: '请输入发现的缺陷数量'
        },
        {
          id: 'textarea2',
          type: 'textarea',
          label: '缺陷描述',
          name: 'bugDescription',
          placeholder: '请描述发现的主要缺陷'
        }
      ]
    };
  } else {
    // 默认表单
    userTaskNodeForm.value = {
      id: `form_${taskId}_${node.id}`,
      taskId: taskId,
      nodeId: node.id,
      formComponents: [
        {
          id: 'input1',
          type: 'input',
          label: '任务完成情况',
          name: 'status',
          placeholder: '请简述任务完成情况'
        },
        {
          id: 'textarea1',
          type: 'textarea',
          label: '详细说明',
          name: 'description',
          placeholder: '请详细描述任务执行过程和结果'
        },
        {
          id: 'select1',
          type: 'select',
          label: '完成状态',
          name: 'completionStatus',
          options: [
            { value: 'completed', label: '已完成' },
            { value: 'partial', label: '部分完成' },
            { value: 'pending', label: '进行中' },
            { value: 'blocked', label: '已阻塞' }
          ]
        }
      ]
    };
  }
  
  // 初始化表单数据
  if (selectedTask.value && selectedTask.value.status === 'completed' && selectedTask.value.submittedFormData) {
    // 已完成任务，使用已提交的表单数据
    formData.value = { ...selectedTask.value.submittedFormData };
  } else {
    // 待处理任务，使用默认值初始化
    formData.value = {};
    userTaskNodeForm.value.formComponents.forEach(component => {
      if (component.type === 'checkbox' || component.type === 'array') {
        formData.value[component.name] = component.defaultValue || [];
      } else {
        formData.value[component.name] = component.defaultValue || '';
      }
    });
  }
};

// 关闭任务详情模态框
const closeTaskDetailModal = () => {
  showTaskDetailModal.value = false;
  selectedTask.value = null;
  selectedTaskProcess.value = { nodes: [] };
  userTaskNodeForm.value = null;
  formData.value = {};
};

// 提交表单
const submitForm = async () => {
  try {
    if (!selectedTask.value) {
      showMessage('任务信息缺失，无法提交', 'error');
      return;
    }
    
    // 准备提交数据
    const submitData = {
      taskApprovalStatusId: selectedTask.value.id,
      comment: JSON.stringify(formData.value), // 将表单数据转为JSON字符串作为comment
      // 判断是否有"是否通过"单选框组
      status: getStatusValue()
    };

    // 获取status值的函数
    function getStatusValue() {
      // 首先检查表单数据中是否有"是否通过"字段
      // 检查comment(JSON字符串)中的"是否通过"值
      try {
        const commentObj = formData.value;
        // 查找是否有"是否通过"相关的字段
        const approvalFieldKey = Object.keys(commentObj).find(key => 
          key.includes('是否通过') || key.includes('审批结果') || key.includes('是否同意')
        );
        
        if (approvalFieldKey) {
          const approvalValue = commentObj[approvalFieldKey];
          console.log('通过字段:', approvalFieldKey, '值:', approvalValue);
          
          // 根据comment中的值设置status
          if (approvalValue === '1' || approvalValue === 1) {
            console.log('comment中是1，status设置为2');
            return 2;
          } else if (approvalValue === '2' || approvalValue === 2) {
            console.log('comment中是2，status设置为3');
            return 3;
          }
        }
      } catch (e) {
        console.error('解析comment失败:', e);
      }
      
      // 如果没有找到"是否通过"字段或解析失败，使用原始逻辑
      if (userTaskNodeForm.value && userTaskNodeForm.value.formComponents) {
        const approvalComponent = userTaskNodeForm.value.formComponents.find(comp => 
          comp.type === 'radio' && 
          comp.label && 
          (comp.label.includes('是否通过') || comp.label.includes('审批结果') || comp.label.includes('是否同意'))
        );
        
        // 如果有审批组件，根据表单值设置status
        if (approvalComponent) {
          const formValue = formData.value[approvalComponent.name];
          console.log('审批组件:', approvalComponent, '组件名称:', approvalComponent.name, '表单值:', formValue);
          
          // 处理各种可能的通过/不通过值
          if (formValue === '通过' || formValue === 1 || formValue === true || 
              formValue === '同意' || formValue === 'yes' || formValue === 'pass') {
            return 2;
          } else if (formValue === '不通过' || formValue === 0 || formValue === false || 
                    formValue === '拒绝' || formValue === 'no' || formValue === 'fail') {
            return 3;
          }
        }
      }
      
      // 如果没有审批组件或值无法确定，默认传2
      console.log('未找到审批组件或值无法确定，默认传2');
      return 2;
    };
    
    console.log('准备提交审批数据:', submitData);
    
    // 调用审批接口
    const response = await taskApprovalService.approveTask(submitData);
    
    console.log('审批接口调用成功:', response);
    showMessage('审批提交成功！', 'success');
    
    // 将提交的任务从待处理任务列表移动到已处理任务列表
    if (selectedTask.value) {
      // 查找任务在待处理列表中的索引
      const taskIndex = userTasks.value.findIndex(task => task.id === selectedTask.value.id);
      
      if (taskIndex !== -1) {
        // 创建已处理任务对象
        const processedTask = {
          ...selectedTask.value,
          status: 'completed',
          processedAt: new Date().toISOString(),
          submittedFormData: formData.value
        };
        
        // 从待处理列表中移除任务
        userTasks.value.splice(taskIndex, 1);
        
        // 添加到已处理列表
        processedTasks.value.unshift(processedTask);
        
        console.log('任务已从待处理移至已处理:', processedTask);
      }
    }
    
    closeTaskDetailModal();
  } catch (error) {
    console.error('提交审批失败:', error);
    showMessage('提交审批失败，请重试', 'error');
  }
};

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleString('zh-CN');
};

// 获取状态文本
const getStatusText = (status) => {
  const statusMap = {
    pending: '待处理',
    processing: '处理中',
    completed: '已完成',
    cancelled: '已取消',
    1: '处理中',
    2: '已完成',
    0: '待处理'
  };
  return statusMap[status] || status;
};

// 格式JSON数据
const formatJsonData = (jsonString) => {
  try {
    if (typeof jsonString === 'string') {
      const parsed = JSON.parse(jsonString);
      return JSON.stringify(parsed, null, 2);
    } else {
      return JSON.stringify(jsonString, null, 2);
    }
  } catch (error) {
    console.error('解析JSON数据失败:', error);
    return jsonString;
  }
};

// 获取数据类型的显示名称
const getItemTypeDisplay = (item) => {
  if (item.value === null) return 'null';
  if (item.value === undefined) return 'undefined';
  if (item.isArray) return 'Array';
  if (item.isObject) return 'Object';
  return typeof item.value;
};

// 切换对象/数组的展开/折叠状态
const toggleExpand = (item) => {
  item.expanded = !item.expanded;
};

// 解析JSON数据为键值对数组
const parseJsonToKeyValuePairs = (jsonString) => {
  try {
    let data = jsonString;
    if (typeof jsonString === 'string') {
      data = JSON.parse(jsonString);
    }
    
    if (typeof data !== 'object' || data === null) {
      return [{ key: 'value', value: data }];
    }
    
    const pairs = [];
    
    // 处理简单对象
    if (!Array.isArray(data)) {
      Object.keys(data).forEach(key => {
        const value = data[key];
        pairs.push({
          key,
          value,
          isObject: typeof value === 'object' && value !== null,
          isArray: Array.isArray(value)
        });
      });
    } else {
      // 处理数组
      data.forEach((item, index) => {
        pairs.push({
          key: `[${index}]`,
          value: item,
          isObject: typeof item === 'object' && item !== null,
          isArray: Array.isArray(item)
        });
      });
    }
    
    return pairs;
  } catch (error) {
    console.error('解析JSON为键值对失败:', error);
    return [{ key: 'raw', value: jsonString, isObject: false, isArray: false }];
  }
};

// 解析节点内容 - 增强版，支持更复杂的JSON格式
const getParsedNodeContent = (nodeContentString) => {
  try {
    if (!nodeContentString) return [];
    
    // 处理字符串类型的内容
    if (typeof nodeContentString === 'string') {
      // 尝试直接解析
      try {
        // 清理字符串，处理可能的JSON字符串周围的多余字符
        const cleanedString = nodeContentString.trim()
          .replace(/^\s*'([\s\S]*)'\s*$/, '$1') // 移除单引号
          .replace(/^\s*"([\s\S]*)"\s*$/, '$1') // 移除双引号
          .replace(/^\s*`([\s\S]*)`\s*$/, '$1') // 移除反引号
          .replace(/\\"/g, '"') // 处理转义的双引号
          .replace(/\\'/g, "'"); // 处理转义的单引号
        
        const parsed = JSON.parse(cleanedString);
        
        // 处理多种可能的数据结构
        if (Array.isArray(parsed)) {
          // 如果是数组，直接返回
          return parsed;
        } else if (typeof parsed === 'object') {
          // 如果是对象，检查是否有components或fields字段
          if (parsed.components && Array.isArray(parsed.components)) {
            return parsed.components;
          } else if (parsed.fields && Array.isArray(parsed.fields)) {
            return parsed.fields;
          } else if (parsed.formComponents && Array.isArray(parsed.formComponents)) {
            return parsed.formComponents;
          } else {
            // 返回对象的所有值（过滤掉非对象类型）
            return Object.values(parsed).filter(val => typeof val === 'object');
          }
        }
        return [];
      } catch (parseError) {
        console.warn('直接解析失败，尝试其他解析方法:', parseError);
        
        // 尝试作为简单文本处理
        return [{ id: 'raw-content', type: 'text', label: '原始内容', value: nodeContentString }];
      }
    } 
    // 处理对象类型的内容
    else if (typeof nodeContentString === 'object') {
      if (Array.isArray(nodeContentString)) {
        return nodeContentString;
      } else if (nodeContentString.components && Array.isArray(nodeContentString.components)) {
        return nodeContentString.components;
      } else if (nodeContentString.fields && Array.isArray(nodeContentString.fields)) {
        return nodeContentString.fields;
      } else if (nodeContentString.formComponents && Array.isArray(nodeContentString.formComponents)) {
        return nodeContentString.formComponents;
      } else {
        return Object.values(nodeContentString).filter(val => typeof val === 'object');
      }
    }
    return [];
  } catch (error) {
    console.error('解析节点内容失败:', error);
    // 提供更好的错误回退机制
    return [{
      id: 'error-content', 
      type: 'text', 
      label: '解析错误', 
      value: '无法解析表单内容，原始数据可能格式不正确',
      description: '请检查原始数据格式是否符合JSON标准'
    }];
  }
};

// 处理数组类型组件的值变化
const handleArrayInputChange = (component, newValue, index) => {
  if (!formData.value[component.name]) {
    formData.value[component.name] = [];
  }
  
  if (index >= 0) {
    // 更新指定索引的值
    formData.value[component.name][index] = newValue;
  } else {
    // 添加新值
    formData.value[component.name] = [...formData.value[component.name], newValue];
  }
};

// 从数组中删除指定索引的值
const removeArrayItem = (component, index) => {
  if (formData.value[component.name] && formData.value[component.name].length > index) {
    formData.value[component.name] = formData.value[component.name].filter((_, idx) => idx !== index);
  }
};

// 获取组件类型显示名称
const getComponentTypeDisplay = (type) => {
  const typeMap = {
    'input': '单行文本输入框',
    'textarea': '多行文本输入框',
    'select': '下拉选择框',
    'radio': '单选按钮',
    'checkbox': '复选框',
    'date': '日期选择器',
    'number': '数字输入框',
    'email': '邮箱输入框',
    'password': '密码输入框',
    'file': '文件上传',
    'switch': '开关按钮',
    'slider': '滑块选择器',
    'rate': '评分组件',
    'upload': '上传组件',
    'text': '文本',
    'hidden': '隐藏字段',
    'range': '范围选择器',
    'color': '颜色选择器',
    'datetime': '日期时间选择器',
    'month': '月份选择器',
    'week': '周选择器',
    'time': '时间选择器',
    'url': 'URL输入框',
    'tel': '电话输入框',
    'search': '搜索框',
    'code': '代码编辑器',
    'markdown': 'Markdown编辑器',
    'richtext': '富文本编辑器',
    'dateRange': '日期范围选择器',
    'cascader': '级联选择器',
    'treeSelect': '树形选择器',
    'transfer': '穿梭框',
    'tag': '标签输入框'
  };
  return typeMap[type] || type || '未知类型';
};

// 检查组件是否有额外属性
const hasExtraProperties = (component) => {
  return component.placeholder || 
         component.defaultValue !== undefined || 
         component.maxLength || 
         (component.options && component.options.length > 0) ||
         component.min ||
         component.max ||
         component.step ||
         component.accept ||
         component.multiple !== undefined ||
         component.readonly !== undefined ||
         component.disabled !== undefined ||
         component.pattern ||
         component.rows ||
         component.cols ||
         component.format ||
         component.dataSource ||
         component.showSearch !== undefined ||
         component.filterOption !== undefined ||
         component.allowClear !== undefined;
};

// 动态生成表单控件的函数
const generateFormControl = (component) => {
  if (!component) return null;
  
  // 为组件创建唯一的ID
  const componentId = component.id || `component-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  
  // 初始化表单数据
  if (formData.value[component.name] === undefined) {
    if (component.type === 'checkbox') {
      formData.value[component.name] = component.defaultValue || [];
    } else if (component.type === 'file') {
      formData.value[component.name] = null;
    } else {
      formData.value[component.name] = component.defaultValue || '';
    }
  }
  
  return {
    id: componentId,
    name: component.name,
    type: component.type,
    label: component.label || component.name || '未命名字段',
    placeholder: component.placeholder || '',
    required: component.required || false,
    options: component.options || [],
    defaultValue: component.defaultValue,
    maxLength: component.maxLength,
    min: component.min,
    max: component.max,
    step: component.step,
    disabled: component.disabled || false,
    accept: component.accept || '*/*',
    multiple: component.multiple || false,
    pattern: component.pattern,
    rows: component.rows || 4,
    cols: component.cols || 50,
    format: component.format,
    showSearch: component.showSearch || false,
    allowClear: component.allowClear || false,
    dataSource: component.dataSource || [],
    filterOption: component.filterOption
  };
};

// 处理文件上传
const handleFileUpload = (event, component) => {
  const { name, multiple, files } = event.target;
  
  if (multiple && files.length > 0) {
    // 处理多文件上传
    const fileList = Array.from(files).map(file => ({
      name: file.name,
      size: file.size,
      type: file.type,
      lastModified: file.lastModified,
      file: file // 保留原始文件对象用于后续处理
    }));
    formData.value[name] = fileList;
  } else if (files.length === 1) {
    // 处理单文件上传
    const file = files[0];
    formData.value[name] = {
      name: file.name,
      size: file.size,
      type: file.type,
      lastModified: file.lastModified,
      file: file // 保留原始文件对象用于后续处理
    };
  } else {
    // 没有选择文件
    formData.value[name] = null;
  }
};

// 处理表单输入变化
const handleFormInput = (event, component) => {
  const { name, type, checked, value } = event.target;
  
  if (type === 'checkbox') {
    if (checked) {
      if (!formData.value[name]) {
        formData.value[name] = [];
      }
      if (!formData.value[name].includes(value)) {
        formData.value[name] = [...formData.value[name], value];
      }
    } else {
      formData.value[name] = formData.value[name]?.filter(item => item !== value) || [];
    }
  } else if (type === 'radio') {
    formData.value[name] = value;
  } else if (type === 'number' || type === 'range') {
    // 处理数字类型
    formData.value[name] = value === '' ? '' : Number(value);
  } else if (type === 'date' || type === 'datetime' || type === 'month' || type === 'week' || type === 'time') {
    // 处理日期时间类型
    formData.value[name] = value;
  } else if (type === 'file') {
    // 文件上传在单独的函数中处理
    handleFileUpload(event, component);
  } else {
    // 处理其他类型
    formData.value[name] = value;
  }
};

// 加载用户已审批任务
const loadProcessedTasks = async () => {
  try {
    // 检查用户ID是否存在
    if (!currentUserId.value) {
      console.error('用户ID不存在，无法加载已处理任务');
      showMessage('用户信息缺失，请重新登录', 'error');
      return;
    }

    console.log('开始加载用户已审批任务，用户ID:', currentUserId.value);
    
    // 调用新接口获取用户已审批任务
    try {
      console.log(`开始调用API: /api/task-approval-status/approver/${currentUserId.value}/approved`);
      
      const response = await taskApprovalService.getApproverApprovedTasks(currentUserId.value);
      
      console.log('已审批任务API调用成功，返回数据:', response);
      
      if (response && response.data) {
        // 处理API返回的数据
        const approvedTasks = Array.isArray(response.data) ? response.data : [];
        console.log(`获取到 ${approvedTasks.length} 个已审批任务记录`);
        
        // 更新已处理任务列表
        processedTasks.value = approvedTasks;
        
        showMessage(`成功加载 ${approvedTasks.length} 个已审批任务`, 'success');
      } else {
        console.warn('已审批任务API返回数据格式异常:', response);
        processedTasks.value = [];
        showMessage('暂无已审批任务数据', 'info');
      }
    } catch (apiError) {
      console.error('已审批任务API调用失败:', apiError);
      
      // API调用失败时使用模拟数据
      console.log('使用已审批任务模拟数据');
      processedTasks.value = generateMockProcessedTasks();
      
      showMessage('已审批任务API调用失败，已加载模拟数据', 'warning');
    }
  } catch (error) {
    console.error('加载已审批任务时发生错误:', error);
    showMessage('加载已审批任务失败', 'error');
  }
};

// 监听activeTab变化
watch(activeTab, (newValue) => {
  if (newValue === 'processed') {
    loadProcessedTasks();
  }
});

// 组件挂载时调用
onMounted(() => {
  checkLoginStatus();
});
</script>

<style scoped>
.user-dashboard-container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background: var(--bg-main);
  position: relative;
  overflow-x: hidden;
}

/* 用户仪表盘独特的背景效果 */
.user-dashboard-container::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 300px;
  background: linear-gradient(135deg, var(--primary-color) 0%, var(--info-color) 100%);
  opacity: 0.05;
  z-index: 0;
  clip-path: polygon(0 0, 100% 0, 100% 70%, 0 100%);
}

.dashboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 30px;
  background: white;
  box-shadow: var(--shadow-base);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border-light);
  transition: all 0.3s ease;
}

.dashboard-header:hover {
  box-shadow: var(--shadow-md);
}

.dashboard-title {
  margin: 0;
  color: var(--text-primary);
  font-size: 24px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 12px;
}

.dashboard-title::before {
  content: '📊';
  font-size: 28px;
}

.logout-button {
  padding: 8px 20px;
  background: var(--danger-color);
  color: white;
  border: none;
  border-radius: var(--border-radius-base);
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  box-shadow: var(--shadow-sm);
}

.logout-button:hover {
  background: #f87171;
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}



.dashboard-content {
  flex: 1;
  padding: 40px;
  margin-top: 80px; /* 为固定的header留出空间 */
  position: relative;
  z-index: 1;
}

.tasks-section {
  max-width: 1200px;
  margin: 0 auto;
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  border-radius: var(--border-radius-md);
  padding: 32px;
  box-shadow: var(--shadow-base);
  border: 1px solid var(--border-light);
}

.section-header {
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 2px solid var(--border-light);
}

.section-header h2 {
  margin: 0;
  color: var(--text-primary);
  font-size: 24px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 12px;
}

.section-header h2::before {
  content: '📋';
  font-size: 24px;
}

.task-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
  gap: 20px;
  animation: fadeIn 0.6s ease;
}

.task-item {
  background: white;
  border-radius: var(--border-radius-md);
  padding: 24px;
  box-shadow: var(--shadow-base);
  display: flex;
  flex-direction: column;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  border: 1px solid var(--border-light);
  position: relative;
  overflow: hidden;
}

.task-item::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 4px;
  height: 100%;
  background: linear-gradient(to bottom, var(--primary-color), var(--info-color));
  opacity: 0;
  transition: opacity 0.3s ease;
}

.task-item:hover::after {
  opacity: 1;
}

.task-item:hover {
  transform: translateY(-2px) scale(1.01);
  box-shadow: var(--shadow-md);
  border-color: var(--primary-color);
}

.task-info {
  flex: 1;
  margin-bottom: 16px;
}

.task-title {
  margin: 0 0 12px 0;
  color: var(--text-primary);
  font-size: 18px;
  font-weight: 600;
  line-height: 1.4;
  transition: color 0.3s ease;
}

.task-item:hover .task-title {
  color: var(--primary-color);
}

.task-meta {
  display: flex;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.task-type {
  color: var(--text-regular);
  font-size: 14px;
  background: var(--bg-light);
  padding: 4px 10px;
  border-radius: var(--border-radius-sm);
  font-weight: 500;
}

.task-status {
  padding: 4px 10px;
  border-radius: var(--border-radius-sm);
  font-size: 12px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.status-pending {
  background-color: #fff7e6;
  color: var(--warning-color);
}

.status-processing {
  background-color: #e6f7ff;
  color: var(--info-color);
}

.status-completed {
  background-color: #f6ffed;
  color: var(--success-color);
}

.status-cancelled {
  background-color: var(--bg-light);
  color: var(--text-secondary);
}

.task-description {
  color: var(--text-regular);
  font-size: 14px;
  line-height: 1.6;
  margin: 0;
  display: -webkit-box;
  display: -moz-box;
  display: box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

.task-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 16px;
}

.no-tasks {
  text-align: center;
  background: white;
  padding: 80px 40px;
  border-radius: var(--border-radius-md);
  box-shadow: var(--shadow-base);
  border: 1px solid var(--border-light);
  animation: fadeIn 0.6s ease;
}

.no-tasks-icon {
  font-size: 64px;
  margin-bottom: 20px;
  color: var(--text-secondary);
  opacity: 0.6;
  transition: transform 0.3s ease;
}

.no-tasks:hover .no-tasks-icon {
  transform: rotate(10deg) scale(1.1);
  color: var(--primary-color);
}

.no-tasks-text {
  margin: 0 0 12px 0;
  color: var(--text-primary);
  font-size: 22px;
  font-weight: 600;
}

.no-tasks-subtext {
  margin: 0;
  color: var(--text-regular);
  font-size: 14px;
  line-height: 1.6;
  max-width: 300px;
  margin: 0 auto;
}

/* 任务标签页样式 */
.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
  flex-wrap: wrap;
  gap: 15px;
}

.section-header h2 {
  margin: 0;
  color: var(--text-primary);
  font-size: 24px;
  font-weight: 600;
}

.task-tabs {
  display: flex;
  gap: 5px;
  background-color: var(--bg-light);
  padding: 3px;
  border-radius: var(--border-radius-md);
  margin: 0;
}

.tab-btn {
  padding: 8px 20px;
  background: none;
  border: none;
  border-radius: var(--border-radius-sm);
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-regular);
  transition: all 0.3s ease;
  position: relative;
}

.tab-btn:hover {
  color: var(--primary-color);
  background-color: rgba(64, 158, 255, 0.08);
}

.tab-btn.active {
  color: white;
  background-color: var(--primary-color);
  font-weight: 600;
}

.tab-btn.active::after {
  display: none;
}

/* 已处理任务特定样式 */
.task-item.processed-task {
  border-left: 4px solid #67c23a;
  background-color: #f0f9eb;
}

.task-item.processed-task .task-info .task-status.status-completed {
  background-color: #67c23a;
  color: white;
}

.task-processed-info {
  margin-top: 10px;
  font-size: 12px;
  color: #909399;
}

.processed-time {
  display: flex;
  align-items: center;
  gap: 5px;
}

/* 弹窗样式已移至 theme.css 统一管理 - VSCode简约风格 */

/* 任务基本信息样式 */
.task-basic-info {
  margin-bottom: 24px;
  background: var(--bg-light);
  padding: 20px;
  border-radius: var(--border-radius-md);
  border: 1px solid var(--border-light);
}

.info-item {
  margin-bottom: 16px;
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
}

.info-item label {
  width: 120px;
  color: var(--text-primary);
  font-weight: 600;
  flex-shrink: 0;
  margin-right: 16px;
  padding: 4px 0;
}

.info-item span {
  color: var(--text-regular);
  flex: 1;
  padding: 4px 0;
  word-break: break-word;
}

/* 只读表单样式 */
.read-only-form {
  margin-top: 4px;
}

.read-only-value {
  padding: 10px 12px;
  background-color: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 4px;
  min-height: 40px;
  line-height: 1.5;
  color: #495057;
  word-break: break-word;
}

.user-node-form-section h4 {
  margin-bottom: 20px;
  font-size: 16px;
  color: #333;
}

.status-badge {
  padding: 4px 10px;
  border-radius: var(--border-radius-sm);
  font-size: 12px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* 流程节点样式 */
.process-nodes-section {
  margin-bottom: 32px;
  background: var(--bg-light);
  padding: 24px;
  border-radius: var(--border-radius-md);
  border: 1px solid var(--border-light);
}

.process-nodes-section h4 {
  margin: 0 0 20px 0;
  color: var(--text-primary);
  font-size: 18px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 10px;
}

.process-nodes-section h4::before {
  content: '📈';
  font-size: 20px;
}

.process-nodes-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  background-color: white;
  border-radius: var(--border-radius-base);
  border: 1px solid var(--border-light);
}

.node-item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 20px;
  background: white;
  border-radius: var(--border-radius-base);
  border-left: 4px solid var(--border-base);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
}

.node-item::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 50%);
  transform: translateX(-100%);
  transition: transform 0.3s ease;
}

.node-item:hover::after {
  transform: translateX(100%);
}

.node-item:hover {
  transform: translateX(2px);
  box-shadow: var(--shadow-md);
}

.node-item.start-node {
  border-left-color: var(--success-color);
  background-color: #f6ffed;
}

.node-item.end-node {
  border-left-color: var(--warning-color);
  background-color: #fff7e6;
}

.node-item.user-node {
  border-left-color: var(--primary-color);
  box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.1);
  background-color: #e6f7ff;
  animation: pulse 2s infinite;
}

.node-icon {
  color: var(--text-secondary);
  flex-shrink: 0;
  font-size: 24px;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--bg-light);
  transition: all 0.3s ease;
}

.node-item:hover .node-icon {
  transform: scale(1.1);
}

.start-node .node-icon {
  color: var(--success-color);
  background: #f6ffed;
}

.end-node .node-icon {
  color: var(--warning-color);
  background: #fff7e6;
}

.user-node .node-icon {
  color: var(--primary-color);
  background: white;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
}

.node-content {
  flex: 1;
}

.node-title {
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 6px;
  font-size: var(--font-size-base);
}

.node-type {
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  background: var(--bg-light);
  padding: 2px 8px;
  border-radius: var(--border-radius-sm);
  display: inline-block;
}

/* 用户节点表单样式 */
.user-node-form-section {
  background-color: var(--bg-white);
  padding: 24px;
  border-radius: var(--border-radius-md);
  box-shadow: var(--shadow-base);
  border: 1px solid var(--border-light);
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.user-node-form-section::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: linear-gradient(90deg, var(--primary-color), var(--info-color));
}

.user-node-form-section:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}

.user-node-form-section:hover {
  box-shadow: var(--shadow-md);
}

.user-node-form-section h4 {
  margin: 0 0 24px 0;
  color: var(--text-primary);
  font-size: var(--font-size-lg);
  font-weight: 600;
  position: relative;
  padding-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.user-node-form-section h4::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 60px;
  height: 3px;
  background: linear-gradient(90deg, var(--primary-color), var(--info-color));
  border-radius: 2px;
}

.user-node-form-section h4::before {
  content: '📝';
  font-size: 20px;
}

.form-container {
  margin-bottom: 24px;
  animation: fadeIn 0.6s ease;
}

.form-component {
  margin-bottom: 24px;
  transition: all 0.3s ease;
  position: relative;
}

.form-component:focus-within {
  transform: translateX(2px);
}

.form-component::after {
  content: '';
  position: absolute;
  bottom: -12px;
  left: 0;
  width: 100%;
  height: 1px;
  background: linear-gradient(to right, var(--border-light), transparent);
}

.form-label {
  display: block;
  margin-bottom: 10px;
  color: var(--text-regular);
  font-weight: 600;
  font-size: var(--font-size-base);
  transition: all 0.3s ease;
  letter-spacing: 0.3px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.form-label.required::after {
  content: '*';
  color: var(--danger-color);
  font-size: 16px;
}

.form-component:focus-within .form-label {
  color: var(--primary-color);
  transform: translateX(2px);
}

.form-component:focus-within .form-label::before {
  content: '→';
  color: var(--primary-color);
  font-size: 12px;
  animation: slideRight 0.3s ease;
}

/* 输入框样式增强 - 用户界面特化 */
.form-control {
  width: 100%;
  padding: 12px 16px;
  border: 2px solid var(--border-base);
  border-radius: var(--border-radius-base);
  font-size: var(--font-size-base);
  font-family: inherit;
  background-color: var(--bg-white);
  color: var(--text-primary);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);
  position: relative;
  z-index: 1;
  backdrop-filter: blur(4px);
}

.form-control:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.15), inset 0 2px 4px rgba(0, 0, 0, 0.05);
  transform: translateY(-1px);
}

.form-control::placeholder {
  color: var(--text-placeholder);
  font-size: var(--font-size-sm);
  transition: color 0.3s ease;
}

.form-control:focus::placeholder {
  color: var(--text-secondary);
  transform: translateX(2px);
}

.form-control.error {
  border-color: var(--danger-color);
  box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.1), inset 0 2px 4px rgba(0, 0, 0, 0.05);
}

.form-control.success {
  border-color: var(--success-color);
  box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.1), inset 0 2px 4px rgba(0, 0, 0, 0.05);
}

/* 文本域样式增强 */
.form-control[type="textarea"],
textarea.form-control {
  min-height: 120px;
  resize: vertical;
  padding: 14px 16px;
  line-height: 1.6;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

textarea.form-control:focus {
  min-height: 140px;
}

/* 选择框样式增强 */
select.form-control {
  appearance: none;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="%2394a3b8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>');
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 40px;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

select.form-control:focus {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="%236366f1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>');
  transform: translateY(-1px);
}

select.form-control:hover {
  border-color: var(--primary-hover);
}

/* 复选框和单选框样式增强 */
.checkbox-group,
.radio-group {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
  padding: 16px 0;
  margin-top: 8px;
}

.checkbox-group label,
.radio-group label {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  color: var(--text-regular);
  font-size: var(--font-size-base);
  transition: all 0.3s ease;
  padding: 10px 16px;
  position: relative;
  border-radius: var(--border-radius-base);
  background: var(--bg-light);
  border: 1px solid var(--border-light);
}

.checkbox-group label:hover,
.radio-group label:hover {
  color: var(--primary-color);
  transform: translateX(2px);
  background: var(--bg-hover);
  border-color: var(--primary-color);
  box-shadow: var(--shadow-sm);
}

.checkbox-group input[type="checkbox"],
.radio-group input[type="radio"] {
  width: 20px;
  height: 20px;
  accent-color: var(--primary-color);
  cursor: pointer;
  transition: all 0.3s ease;
  flex-shrink: 0;
}

.checkbox-group input[type="checkbox"]:hover,
.radio-group input[type="radio"]:hover {
  transform: scale(1.1);
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
}

.checkbox-group input[type="checkbox"]:checked,
.radio-group input[type="radio"]:checked {
  transform: scale(1.1);
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
}

.checkbox-group input[type="checkbox"]:checked + span,
.radio-group input[type="radio"]:checked + span {
  color: var(--primary-color);
  font-weight: 500;
}

/* 表单操作按钮区域 - 增强视觉效果 */
.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 16px;
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--border-light);
  background: var(--bg-light);
  padding: 24px;
  border-radius: 0 0 var(--border-radius-base) var(--border-radius-base);
  margin: 24px -24px -24px -24px;
}

/* 表单验证状态提示 - 增强视觉效果 */

/* 数组类型组件样式优化 */
.array-component {
  background: var(--bg-light);
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-base);
  padding: 20px;
  transition: all 0.3s ease;
}

.array-component:hover {
  border-color: var(--primary-color);
  box-shadow: var(--shadow-sm);
}

.array-items {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 16px;
}

.array-item {
  display: flex;
  align-items: center;
  gap: 12px;
  transition: all 0.3s ease;
  padding: 12px;
  background: white;
  border-radius: var(--border-radius-base);
  border: 1px solid var(--border-light);
  position: relative;
  overflow: hidden;
}

.array-item::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 4px;
  background: var(--primary-color);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.array-item:hover::before {
  opacity: 1;
}

.array-item-input {
  flex: 1;
  transition: all 0.3s ease;
  background: white;
}

.array-remove-btn {
  flex-shrink: 0;
  padding: 8px 16px;
  font-size: 12px;
  border-radius: var(--border-radius-sm);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  background-color: var(--danger-color);
  color: white;
  border: none;
  cursor: pointer;
  height: 40px;
}

.array-remove-btn:hover:not(:disabled) {
  background-color: #dc2626;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.2);
}

.array-remove-btn:active:not(:disabled) {
  transform: translateY(0);
}

.array-remove-btn:disabled {
  background-color: var(--bg-light);
  color: var(--text-disabled);
  cursor: not-allowed;
}

.array-add-btn {
  width: 100%;
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 500;
  border-radius: var(--border-radius-base);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  background-color: var(--primary-color);
  color: white;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.array-add-btn:hover:not(:disabled) {
  background-color: var(--primary-hover);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(99, 102, 241, 0.2);
}

.array-add-btn:active:not(:disabled) {
  transform: translateY(0);
}

.array-add-btn:disabled {
  background-color: var(--bg-light);
  color: var(--text-disabled);
  cursor: not-allowed;
}

/* 只读模式下的数组样式优化 */
.read-only-value .array-item {
  display: inline-block;
  padding: 6px 12px;
  margin: 2px 4px;
  background-color: var(--primary-light);
  color: var(--primary-color);
  border-radius: var(--border-radius-sm);
  font-size: var(--font-size-sm);
  border: 1px solid var(--primary-border);
  transition: all 0.2s ease;
}

.read-only-value .array-item:hover {
  background-color: var(--primary-color);
  color: white;
  transform: scale(1.05);
}

/* 响应式布局优化 */
@media (max-width: 768px) {
  .array-item {
    flex-direction: column;
    align-items: stretch;
  }
  
  .array-remove-btn {
    width: 100%;
  }
}
.form-error {
  color: var(--danger-color);
  font-size: var(--font-size-xs);
  margin-top: 8px;
  display: block;
  animation: fadeIn 0.3s ease;
  padding-left: 24px;
  position: relative;
  line-height: 1.4;
}

.form-error::before {
  content: '⚠';
  position: absolute;
  left: 4px;
  top: 0;
  font-size: 14px;
  background: var(--danger-color);
  color: white;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
}

.form-success {
  color: var(--success-color);
  font-size: var(--font-size-xs);
  margin-top: 8px;
  display: block;
  animation: fadeIn 0.3s ease;
  padding-left: 24px;
  position: relative;
  line-height: 1.4;
}

.form-success::before {
  content: '✓';
  position: absolute;
  left: 4px;
  top: 0;
  font-size: 14px;
  background: var(--success-color);
  color: white;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
}

/* 按钮样式已移至 theme.css 统一管理 */

.btn-primary {
  background: linear-gradient(135deg, var(--primary-color), var(--info-color));
  color: white;
  border: 1px solid var(--primary-color);
}

/* 用户信息栏样式 */
.dashboard-header {
  background-color: var(--primary-color);
  color: #ffffff;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 var(--spacing-xl);
  height: 60px;
  box-shadow: var(--shadow-base);
  position: sticky;
  top: 0;
  z-index: 100;
}

.user-menu-container {
  position: relative;
}

.user-menu-button {
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: none;
  color: white;
  padding: 8px 12px;
  border-radius: var(--border-radius-base);
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: var(--font-size-base);
  font-weight: 500;
  min-width: 120px;
  justify-content: center;
}

.user-menu-button:hover {
  background: rgba(255, 255, 255, 0.1);
  transform: translateY(-1px);
}

.user-avatar {
  width: 32px;
  height: 32px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.chevron {
  transition: transform 0.3s ease;
}

.user-menu-button:hover .chevron {
  transform: rotate(180deg);
}

.user-dropdown {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 4px;
  background: white;
  border-radius: var(--border-radius-base);
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
  min-width: 280px;
  overflow: hidden;
  z-index: 1000;
  animation: slideIn 0.3s ease;
}

.dropdown-header {
  padding: 16px;
  background: var(--primary-color);
  color: white;
}

.user-info {
  text-align: center;
}

.user-name {
  font-size: var(--font-size-base);
  font-weight: 600;
  margin-bottom: 4px;
}

.user-role {
  font-size: var(--font-size-sm);
  opacity: 0.9;
}

.user-details {
  padding: 16px;
}

.user-detail-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-light);
}

.user-detail-item:last-child {
  border-bottom: none;
}

.user-detail-item label {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  font-weight: 500;
}

.user-detail-item span {
  font-size: var(--font-size-sm);
  color: var(--text-primary);
}

.dropdown-divider {
  height: 1px;
  background: var(--border-light);
  margin: 0;
}

.logout-button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 12px 16px;
  background: var(--danger-color);
  color: white;
  border: none;
  cursor: pointer;
  font-size: var(--font-size-base);
  font-weight: 500;
  transition: all 0.3s ease;
}

.logout-button:hover {
  background: var(--danger-hover);
  transform: translateY(-1px);
}

.logout-button:active {
  transform: translateY(0);
}

.btn-primary:hover {
  background: linear-gradient(135deg, var(--primary-hover), var(--info-color));
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.btn-primary:active {
  background: linear-gradient(135deg, var(--primary-active), var(--primary-color));
  transform: translateY(0);
}

.btn-primary:disabled {
  background: #c7d2fe;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.btn-secondary {
  background-color: var(--bg-white);
  color: var(--text-regular);
  border: 1px solid var(--border-base);
}

.btn-secondary:hover {
  background-color: var(--bg-hover);
  color: var(--primary-color);
  border-color: var(--primary-color);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

/* 范围选择器样式 */
.range-input {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
  height: 6px;
  background: var(--bg-light);
  border-radius: 3px;
  outline: none;
  transition: all 0.3s ease;
}

.range-input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  background: var(--primary-color);
  border-radius: 50%;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 2px 6px rgba(99, 102, 241, 0.3);
}

.range-input::-moz-range-thumb {
  width: 20px;
  height: 20px;
  background: var(--primary-color);
  border-radius: 50%;
  cursor: pointer;
  transition: all 0.3s ease;
  border: none;
  box-shadow: 0 2px 6px rgba(99, 102, 241, 0.3);
}

.range-input:hover::-webkit-slider-thumb {
  transform: scale(1.2);
  box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
}

.range-input:hover::-moz-range-thumb {
  transform: scale(1.2);
  box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
}

.range-input:focus {
  box-shadow: none;
  outline: none;
}

.range-input:focus::-webkit-slider-thumb {
  transform: scale(1.2);
  box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
}

.range-input:focus::-moz-range-thumb {
  transform: scale(1.2);
  box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
}

/* 颜色选择器样式 */
.color-input {
  width: 80px;
  height: 50px;
  padding: 4px;
  border: 2px solid var(--border-base);
  border-radius: var(--border-radius-base);
  cursor: pointer;
  transition: all 0.3s ease;
  background: white;
}

.color-input:hover {
  border-color: var(--primary-color);
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.2);
  transform: translateY(-1px);
}

.color-input:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.15);
}

/* 动画定义 */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(-20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes slideRight {
  from {
    opacity: 0;
    transform: translateX(-10px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes pulse {
  0% {
    box-shadow: 0 4px 12px rgba(99, 102, 241, 0.2);
  }
  50% {
    box-shadow: 0 4px 20px rgba(99, 102, 241, 0.3);
  }
  100% {
    box-shadow: 0 4px 12px rgba(99, 102, 241, 0.2);
  }
}

/* 响应式设计 - 增强移动端体验 */
@media (max-width: 768px) {
  .user-dashboard-container {
    padding: 0;
  }
  
  .dashboard-header {
    padding: 20px 16px;
  }
  
  .dashboard-title {
    font-size: 24px;
  }
  
  .dashboard-content {
    padding: 20px 16px;
  }
  
  .tasks-section {
    padding: 20px;
  }
  
  .task-list {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  
  .task-item {
    padding: 16px;
  }
  
  /* 弹窗样式已移至 theme.css 统一管理 - VSCode简约风格 */
  
  .process-nodes-container {
    padding: 16px;
    gap: 12px;
  }
  
  .node-item {
    padding: 12px 16px;
    min-width: 160px;
  }
  
  .form-container {
    padding: 20px;
  }
  
  .form-actions {
    flex-direction: column-reverse;
    gap: 12px;
  }
  
  .btn {
    width: 100%;
    padding: 12px 20px;
  }
  
  .checkbox-group,
  .radio-group {
    flex-direction: column;
    gap: 8px;
  }
  
  /* 表单设计器组件移动端适配 */
  .component-properties {
    grid-template-columns: 1fr;
  }
  
  .component-header {
    flex-wrap: wrap;
    gap: 8px;
  }
  
  .component-title-info {
    min-width: 200px;
  }
}

@media (max-width: 480px) {
  .dashboard-title {
    font-size: 20px;
  }
  
  .logout-button {
    padding: 8px 16px;
    font-size: 14px;
  }
  
  .section-header h2 {
    font-size: 18px;
  }
  
  .task-title {
    font-size: 16px;
  }
  
  .modal-header h3 {
    font-size: 18px;
  }
}

/* 新增样式用于显示任务数据 */
.task-id, .task-flow-id, .task-node-id {
  background-color: var(--bg-light);
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  margin-right: 8px;
  color: var(--text-secondary);
}

.task-details {
  margin-top: 12px;
}

.task-details p {
  margin: 4px 0;
  font-size: 14px;
  color: var(--text-regular);
}

.task-approver {
  font-weight: 500;
}

/* JSON数据显示样式 */
.data-container {
  background-color: var(--bg-light);
  border-radius: 8px;
  padding: 16px;
  margin: 12px 0;
  border: 1px solid var(--border-light);
}

.json-data {
  background-color: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 4px;
  padding: 12px;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.4;
  color: #333;
  overflow-x: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 300px;
  overflow-y: auto;
}

/* 表单设计器组件显示样式 */
.form-designer-components {
  margin-top: 16px;
}

.form-designer-info {
  background-color: #f0f9ff;
  border: 1px solid #0ea5e9;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 20px;
}

.section-description {
  margin: 0;
  color: #0c4a6e;
  font-size: 14px;
  font-weight: 500;
}

.form-components-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.form-component-card {
  background-color: var(--bg-white);
  border: 2px solid var(--border-light);
  border-radius: 12px;
  padding: 20px;
  box-shadow: var(--shadow-sm);
  transition: all 0.3s ease;
}

.form-component-card:hover {
  border-color: var(--primary-color);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

/* 组件头部 */
.component-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-light);
}

.component-icon-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: linear-gradient(135deg, var(--primary-color), var(--info-color));
  border-radius: 10px;
  box-shadow: var(--shadow-sm);
}

.component-icon {
  font-size: 20px;
  color: white;
}

.component-title-info {
  flex: 1;
}

.component-name {
  margin: 0 0 4px 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
}

.component-type-badge {
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
}

.component-required-badge {
  background: linear-gradient(135deg, #ef4444, #dc2626);
  color: white;
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
}

.required-text {
  font-size: 11px;
}

/* 组件主体 */
.component-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.component-label {
  background-color: var(--bg-light);
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 14px;
  color: var(--text-primary);
}

.component-properties {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 8px;
}

.property-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #f8fafc;
  padding: 6px 10px;
  border-radius: 6px;
  border: 1px solid #e2e8f0;
}

.property-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
}

.property-value {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
}

.required-yes {
  color: #dc2626;
  font-weight: 700;
}

.required-no {
  color: #059669;
  font-weight: 500;
}

/* 额外属性 */
.component-extra-props {
  background-color: #fefce8;
  border: 1px solid #eab308;
  border-radius: 8px;
  padding: 12px;
  margin-top: 8px;
}

.task-type-description {
  background-color: #f8fafc;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 16px;
  border: 1px solid #e2e8f0;
}

.task-type-description h4 {
  color: var(--text-primary);
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 12px 0;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--primary-color);
}

.task-type-name {
  display: flex;
  align-items: flex-start;
  margin-bottom: 12px;
}

.task-type-name label {
  font-weight: 600;
  color: var(--text-secondary);
  margin-right: 8px;
  min-width: 80px;
}

.task-type-name span {
  color: var(--text-primary);
  flex: 1;
}

.task-description {
  margin-top: 12px;
}

.task-description label {
  display: block;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

/* markdown文本样式 */
.markdown-text {
  color: var(--text-primary);
  line-height: 1.6;
}

.markdown-text h1,
.markdown-text h2,
.markdown-text h3,
.markdown-text h4,
.markdown-text h5,
.markdown-text h6 {
  margin-top: 16px;
  margin-bottom: 8px;
  font-weight: 600;
  color: var(--primary-color);
}

.markdown-text h1 {
  font-size: 24px;
  border-bottom: 2px solid var(--border-color);
  padding-bottom: 8px;
}

.markdown-text h2 {
  font-size: 20px;
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 6px;
}

.markdown-text h3 {
  font-size: 18px;
}

.markdown-text h4 {
  font-size: 16px;
}

.markdown-text p {
  margin-bottom: 12px;
}

.markdown-text strong {
  font-weight: 600;
  color: var(--text-primary);
}

.markdown-text em {
  font-style: italic;
}

.markdown-text ul,
.markdown-text ol {
  padding-left: 24px;
  margin-bottom: 12px;
}

.markdown-text li {
  margin-bottom: 4px;
}

.markdown-text a {
  color: var(--primary-color);
  text-decoration: underline;
}

.markdown-text a:hover {
  color: var(--primary-hover);
}

.component-extra-props h6 {
  margin: 0 0 8px 0;
  font-size: 13px;
  font-weight: 600;
  color: #a16207;
}

.extra-props-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.extra-prop {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.prop-name {
  font-size: 12px;
  font-weight: 600;
  color: #a16207;
  min-width: 80px;
}

.prop-value {
  font-size: 12px;
  color: #374151;
  flex: 1;
}

.options-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.option-item {
  background-color: #dbeafe;
  color: #1e40af;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
}

/* 备用JSON显示 */
.fallback-json-display {
  margin-top: 16px;
}

.fallback-info {
  color: var(--text-secondary);
  font-size: 14px;
  margin-bottom: 8px;
  font-style: italic;
}

/* 键值对列表样式 */
.key-value-list {
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.key-value-item {
  background: white;
  border: 1px solid var(--border-light);
  border-radius: 8px;
  min-height: 100px;
  transition: all 0.3s ease;
}

.key-value-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  border-color: var(--primary-color-light);
}

.key-value-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: var(--bg-ultra-light);
  border-bottom: 1px solid var(--border-light);
  border-radius: 8px 8px 0 0;
}

.data-key {
  font-weight: 600;
  color: var(--text-primary);
  font-size: 14px;
}

/* 数据类型徽章样式 */
.data-type-badge {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 12px;
  font-weight: 500;
}

.badge-object {
  background: var(--primary-color-light);
  color: var(--primary-color);
}

.badge-array {
  background: var(--success-color-light);
  color: var(--success-color);
}

.badge-string {
  background: var(--warning-color-light);
  color: var(--warning-color);
}

.badge-number {
  background: var(--info-color-light);
  color: var(--info-color);
}

.badge-boolean {
  background: var(--error-color-light);
  color: var(--error-color);
}

.badge-null {
  background: var(--text-disabled-light);
  color: var(--text-disabled);
}

/* 数据值样式 */
.data-value {
  padding: 12px 16px;
}

.simple-value {
  font-family: 'Courier New', monospace;
  font-size: 13px;
  color: var(--text-secondary);
  word-break: break-word;
  line-height: 1.6;
}

.complex-value {
  font-family: 'Courier New', monospace;
  font-size: 12px;
  color: var(--text-secondary);
  white-space: pre-wrap;
  background: var(--bg-ultra-light);
  padding: 12px;
  border-radius: 6px;
  border: 1px solid var(--border-light);
}

/* 可展开内容样式 */
.expandable-content {
  position: relative;
}

.expanded-content {
  animation: slideDown 0.3s ease;
}

.collapsed-content {
  text-align: center;
  padding: 8px 0;
}

.expand-button {
  background: var(--bg-light);
  border: 1px dashed var(--border-light);
  color: var(--text-secondary);
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.expand-button:hover {
  background: var(--primary-color-light);
  border-color: var(--primary-color);
  color: var(--primary-color);
}

/* 嵌套内容样式 */
.nested-key-value-list {
  margin-left: 20px;
  margin-top: 8px;
}

.nested-key-value-item {
  background: var(--bg-ultra-light);
  border: 1px solid var(--border-light);
  border-radius: 6px;
  margin-bottom: 6px;
}

.nested-key-value-item .key-value-header {
  padding: 8px 12px;
  font-size: 12px;
}

.nested-key-value-item .data-value {
  padding: 8px 12px;
}

/* 数组内容样式 */
.array-content {
  margin-top: 8px;
}

.array-item-count {
  font-size: 12px;
  color: var(--text-tertiary);
  margin-bottom: 8px;
  padding: 4px 8px;
  background: var(--bg-ultra-light);
  border-radius: 6px;
  text-align: center;
}

/* 对象内容样式 */
.object-content {
  font-family: 'Courier New', monospace;
  font-size: 12px;
  color: var(--text-secondary);
  white-space: pre-wrap;
  background: var(--bg-ultra-light);
  padding: 12px;
  border-radius: 6px;
  border: 1px solid var(--border-light);
}

/* 无数据样式 */
.no-data {
  text-align: center;
  color: var(--text-tertiary);
  font-size: 14px;
  padding: 20px;
  background: var(--bg-ultra-light);
  border-radius: 8px;
}

/* 动画效果 */
@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 数据区域标题 */
.raw-data-section h4,
.extra-fields-section h4,
.node-content-section h4 {
  color: var(--text-primary);
  font-size: 16px;
  font-weight: 600;
  margin: 20px 0 12px 0;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--primary-color);
}

</style>